package com.example.core.tag;

import cn.hutool.core.bean.BeanUtil;
import com.example.core.convert.Convertor;
import com.example.core.form.BaseForm;
import com.example.sys.module.mode.SysColumnInfo;
import com.example.sys.module.mode.SysModuleInfo;
import com.example.sys.module.service.SysModuleService;
import com.example.utils.SpringUtils;
import com.example.utils.StringUtils;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;

@Data
public class XSelect extends BodyTagSupport {

    Logger logger = LoggerFactory.getLogger(getClass());

    public SysModuleService sysModuleService;

    private String titleWidth = "15%";

    private String propertyName;

    private String propertyId;

    private String colspan;

    private String width = "35%";

    private Boolean required = false;

    private Boolean readonly = false;

    private Boolean multi = false;

    private String placeholder;

    private String modelPref;

    public SysModuleInfo getSysModuleInfo(PageContext pageContext) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) pageContext.getRequest();
        String entityName = (String) httpServletRequest.getAttribute("entityName");
        if (!StringUtils.isEmpty(entityName)) {
            return this.getSysModuleService().getSysModuleInfoBySimpleName(entityName);
        }
        return null;
    }

    public SysModuleService getSysModuleService() {
        if (sysModuleService == null) {
            sysModuleService = (SysModuleService) SpringUtils.getBean(SysModuleService.class);
        }
        return sysModuleService;
    }

    public Object getDefaultValue(PageContext pageContext, String property) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) pageContext.getRequest();
        String formName = (String) httpServletRequest.getAttribute("formName");
        if (!StringUtils.isEmpty(formName)) {
            BaseForm baseForm = (BaseForm) httpServletRequest.getAttribute(formName);
            return BeanUtil.getFieldValue(baseForm, property);
        }
        return null;
    }

    @Override
    public int doStartTag() throws JspException {
        JspWriter out = pageContext.getOut();
        SysModuleInfo sysModuleInfo = this.getSysModuleInfo(pageContext);
        try {
            SysColumnInfo sysColumnInfo = sysModuleInfo.getSysColumnInfo(this.propertyName);
            if (!StringUtils.isEmpty(sysColumnInfo.getComment())) {
                out.print("<td class=\"tb-title\" style=\"width: " + titleWidth + "\"> " + sysColumnInfo.getComment() + "</td>");
            } else {
                out.print("<td class=\"tb-title\" style=\"width: " + titleWidth + "\"></td>");
            }
            if (StringUtils.isEmpty(this.colspan)) {
                out.print("<td style=\"width: " + this.width + "\">");
            } else {
                out.print(" <td colspan=\"" + this.colspan + "\">");
            }
            out.print("<div id=\"" + this.propertyId + "\"></div>");
        } catch (Exception e) {
            logger.warn("XSelect doStartTag error " + e.getMessage());
        }
        return EVAL_BODY_INCLUDE;
    }

    @Override
    public int doEndTag() throws JspException {
        JspWriter out = pageContext.getOut();
        try {
            out.print("<script>");
            out.print(" layui.use(['xmSelect'], function () { ");
            out.print(" var xmSelect = layui.xmSelect;");
            out.print(" var $ = layui.$;");
            out.print(" var node = xmSelect.render({");
            out.print(" el: '#" + this.propertyId + "',");
            if (!this.multi) {
                out.print(" radio: true,");
            }
            out.print(" filterable: true,");
            out.print(" paging: true,");
            out.print(" pageSize: 10,");
            out.print("");
            out.print("");
            out.print("");
            out.print(" toolbar: {show: true},");
            out.print(" height: 'auto',");
            out.print(" remoteSearch: true,");
            out.print(" pageRemote: true,");
            out.print(" name: '" + this.propertyId + "',");
            if (this.required) {
                out.print(" layVerify: 'required',");
            }
            if (!StringUtils.isEmpty(this.placeholder)) {
                out.print(" tips: ' " + this.placeholder + "',");
            }
            out.print(" prop: {");
            out.print(" name: 'fdName',");
            out.print(" value: 'fdId'");
            out.print(" },");
            out.print(" data: [],");
            out.print(" remoteMethod: function (val, cb, show ,pageIndex) {");
            out.print(" $.ajax({");
            out.print("  method: 'POST',");
            out.print("  url: '/" + this.modelPref + "/data',");
            out.print("  data: {fdName: val , pageNum: pageIndex},");
            out.print(" success: function (data) {");
            out.print("  if (data) {");
            out.print(" return cb(data.list, data.total);");
            out.print(" }");
            out.print(" return cb([]);");
            out.print(" }");
            out.print("  });");
            out.print("  }");
            out.print(" });");
            String idStr = (String) this.getDefaultValue(pageContext, this.propertyId);
            if (!StringUtils.isEmpty(idStr)) {
                String nameStr = (String) this.getDefaultValue(pageContext, this.propertyName);
                out.print("node.setValue([");
                String[] idArr = idStr.split(Convertor.PATH);
                String[] nameArr = nameStr.split(Convertor.PATH);
                for (int i = 0; i < idArr.length; i++) {
                    out.print("{fdName: '" + nameArr[i] + "', fdId: '" + idArr[i] + "'},");
                }
                out.print("]);");
            }
            out.print(" });");
            out.print(" </script>");
        } catch (Exception e) {
            logger.warn("XSelect doEndTag error " + e.getMessage());
        }
        return EVAL_PAGE;
    }
}
